﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Wicture.DbRESTFul.SQL;
using Wicture.EPC.Common;
using Wicture.EPC.Service.V1.Filters;
using Wicture.EPC.Service.V1.Models;
using Wicture.EPC.Service.V1.Repository;

namespace Wicture.EPC.Service.V1.QueryInterceptors.Interceptors
{
    public class SubaruQueryInterceptor : BaseQueryInterceptor
    {
        private readonly string[] brandCodes = new string[] { "subaru" };
        public override string[] BrandCodes => brandCodes;

        public override object QuerySubGroup(DbRESTFulRepository repository, JObject param)
        {
            param.RemoveEmptyValues();
            string vin = param.Value<string>(ParamFields._vin);
            if(string.IsNullOrEmpty(vin))
            {
               return repository.Invoke<Query_SubGroupResult>(CSIs.Query_SubGroup_For_Subaru, param);
            }
            else
            {
                dynamic vinInfo = QueryVinByCode(repository, new Get_Model_InfoParam { vin = vin });
                string modelCode = vinInfo.code;
                int productionDate = vinInfo.productionDate;
                List<Query_SubGroupResult> subGroups = repository.Invoke<Query_SubGroupResult>(CSIs.Query_SubGroup_By_Vin_For_Subaru, new { modelCode, productionDate, mainGroupCode = param.Value<string>(ParamFields._id)});
                var vinFeatures = GetVinFeatures(vinInfo);
                foreach(var subGroup in subGroups)
                {
                    if (string.IsNullOrEmpty(subGroup.specCodes))
                    {
                        continue;
                    }
                    UCStringSubaru uCString = new UCStringSubaru(subGroup.specCodes);
                    if(!uCString.IsMatch(vinFeatures))
                    {
                        subGroup.belongTo = false;
                    }
                }
                return subGroups;
            }
        }

        public override object QueryParts(DbRESTFulRepository repository, JObject param)
        {
            param.RemoveEmptyValues();
            string vin = param.Value<string>(ParamFields._vin);
            string selectorId = param.Value<string>(ParamFields._selectorId);
            _subgroupId = param.Value<string>(ParamFields._id);

            List<Query_PartsResult> result = new List<Query_PartsResult>();

            if (string.IsNullOrEmpty(vin))
            {
                result = repository.Invoke<Query_PartsResult>(CSIs.Query_Parts_For_Subaru, param);
            }
            else
            {
                dynamic vinInfo = QueryVinByCode(repository, new Get_Model_InfoParam { vin = vin });
                string modelCode = vinInfo.code;
                int productionDate = vinInfo.productionDate;
                result = repository.Invoke<Query_PartsResult>(CSIs.Query_Parts_By_Vin_For_Subaru, new { modelCode, productionDate, subGroupCode = param.Value<string>(ParamFields._id) });
                string destinationCode = vinInfo.destinationCode;
                string cColour = vinInfo.cColour;
                string tColour = vinInfo.tColour;
                var vinFeatures = GetVinFeatures(vinInfo);
                foreach (var item in result)
                {
                    if (!string.IsNullOrEmpty(item.countryCode) && !string.IsNullOrEmpty(destinationCode))
                    {
                        bool flag = false;
                        for(int i =0;i< item.countryCode.Length; i = i + 2)
                        {
                            if(item.countryCode.Substring(i,2) == destinationCode)
                            {
                                flag = true;
                                break;
                            }
                        }
                        if (!flag)
                        {
                            item.belongToVin = false;
                            continue;
                        }
                    }

                    if (!string.IsNullOrEmpty(item.colorCodes))
                    {
                        string targetColor = "";
                        if(item.bodyColor == "T")
                        {
                            targetColor = tColour;
                        }
                        else if(item.bodyColor == "C")
                        {
                            targetColor = cColour;
                        }
                        if (!string.IsNullOrEmpty(targetColor))
                        {
                            bool flag = false;
                            for (int i = 0; i < item.colorCodes.Length; i = i + 3)
                            {
                                if (item.colorCodes.Substring(i, 3) == targetColor)
                                {
                                    flag = true;
                                    break;
                                }
                            }
                            if (!flag)
                            {
                                item.belongToVin = false;
                                continue;
                            }
                        } 
                    }

                    if (string.IsNullOrEmpty(item.featureCodes))
                    {
                        continue;
                    }
                    try
                    {
                        UCStringSubaru uCString = new UCStringSubaru(item.featureCodes);
                        if (!uCString.IsMatch(vinFeatures))
                        {
                            item.belongToVin = false;
                        }
                    }
                    catch
                    {
                        var a = item.featureCodes;
                    }

                }
            }
            return BuildPartResults(result);
        }
        protected override List<Query_PartsResult> BuildPartResults(List<Query_PartsResult> result)
        {
            return result.GroupBy(q => new { q.imageSN, q.partCode, q.quantity, }).Select(q => new Query_PartsResult
            {
                id = q.First().id,
                imageSN = q.Key.imageSN,
                partCode = q.Key.partCode,
                partName = q.First().partName,
                quantity = q.Key.quantity,
                modelNotes = string.Join("$$", q.Select(x => x.modelNotes).Distinct()),
                notes = string.Join("$$", q.Select(x => x.notes).Distinct()),
                replacedPartCodes = q.First().replacedPartCodes,
                cost = q.First().cost,
                price = q.First().price,
                priceUpdatedAt = q.First().priceUpdatedAt,
                belongToVin = q.Any(x => x.belongToVin),
                brandCode = q.First().brandCode,
                brandName = q.First().brandName
            }).ToList();
        }

        private ISet<string> GetVinFeatures(dynamic vinInfo)
        {
            ISet<string> set = new HashSet<string>();
            if (!string.IsNullOrEmpty(vinInfo.option1))
            {
                set.Add(vinInfo.option1);
            }
            if (!string.IsNullOrEmpty(vinInfo.option2))
            {
                set.Add(vinInfo.option2);
            }
            if (!string.IsNullOrEmpty(vinInfo.option3))
            {
                set.Add(vinInfo.option3);
            }
            if (!string.IsNullOrEmpty(vinInfo.option4))
            {
                set.Add(vinInfo.option4);
            }
            if (!string.IsNullOrEmpty(vinInfo.option5))
            {
                set.Add(vinInfo.option5);
            }
            if (!string.IsNullOrEmpty(vinInfo.option6))
            {
                set.Add(vinInfo.option6);
            }
            if (!string.IsNullOrEmpty(vinInfo.option7))
            {
                set.Add(vinInfo.option7);
            }
            return set;
        }

        public override object QueryPartDetail(DbRESTFulRepository repository, JObject param)
        {
            param.RemoveEmptyValues();
            var brandCode = param.Value<string>(ParamFields._brandCode);
            var partId = param.Value<string>(ParamFields._partId);
            var partCode = param.Value<string>(ParamFields._partCode);
            dynamic data = null;

            if (string.IsNullOrEmpty(partId))
            {
                data = repository.Invoke(CSIs.Get_Part_Detail_Standard, new { partCode, brandCode });
            }
            else
            {
                data = repository.Invoke(CSIs.Get_Usage_Detail_Standard, param);
            }
            if (data == null) return null;
            // 1、基本信息赋值
            Query_Part_DetailResult result = JObject.FromObject(data).ToObject<Query_Part_DetailResult>();

            result.replacements = new List<Query_Part_DetailResult._replacement>();
            //3.替换件处理
            if (!string.IsNullOrEmpty(result.replacementPartNo))
            {
                List<Query_Part_DetailResult._replacement> replacements = repository.Invoke<Query_Part_DetailResult._replacement>(CSIs.Query_Parts_By_Codes, new { partCodes = result.replacementPartNo.Split(',') });
                if (replacements != null)
                {
                    foreach (var replacement in replacements)
                    {
                        replacement.brandCode = brandCode;
                        replacement.brandName = BrandDictionary.GetName(brandCode);
                        result.replacements.Add(replacement);
                    }
                }
            }
            //4.配件附加属性处理
            var props = new List<Query_Part_DetailResult._prop>
            {
                new Query_Part_DetailResult._prop { key = "件数", value = result.quantity ?? string.Empty },
            };
            result.props = props.Where(q => !string.IsNullOrEmpty(q.value)).ToList();
            return result;
        }

        protected override List<Query_MainGroupResult> GetMainGroup(DbRESTFulRepository repository, JObject param)
        {
            return repository.Invoke<Query_MainGroupResult>(CSIs.Query_Main_Group_For_Subaru, param);
        }

        protected override SubGroupInfo GetSubGroupForCrumb(DbRESTFulRepository repository, JObject param)
        {
            return repository.Invoke<SubGroupInfo>(CSIs.Get_SubGroup_By_Code, param);
        }

        protected override dynamic GetMainGroupForCrumb(DbRESTFulRepository repository, JObject param)
        {
            return repository.Invoke(CSIs.Get_MainGroup_By_Code, param);
        }

        protected override IEnumerable<dynamic> GetHotPoints(DbRESTFulRepository repository, JObject param)
        {
            return repository.Invoke(CSIs.Query_HotPoints_For_Subaru, param);
        }

        protected override dynamic GetModelsByPart(DbRESTFulRepository repository, int pageIndex, int pageSize, string brandCode, string partCode)
        {
            return repository.Invoke(CSIs.Query_Models_By_Part_For_Subaru, new { pageIndex, pageSize, brandCode, partCode });
        }

        protected override dynamic GetHotPointsByPart(DbRESTFulRepository repository, string brandCode, string partCode, IEnumerable<string> imageIds)
        {
            return repository.Invoke(CSIs.Query_HotPoints_By_Part_For_Subaru, new { brandCode, partCode, imageIds });
        }

        protected override List<SearchSubGroupResults> GetSearchResults(DbRESTFulRepository repository, string brandCode, string[] partCodes, string selectorId)
        {
            return repository.Invoke<SearchSubGroupResults>(CSIs.Search_SubGroups_By_PartCodes_For_Subaru, new { brandCode, partCodes, selectorId });
        }

        protected override dynamic QueryVinByCode(DbRESTFulRepository repository, Get_Model_InfoParam param)
        {
            return repository.Invoke(CSIs.Query_Vin_By_Code_For_Subaru, param);
        }

        protected override List<Get_Model_InfoResult._props> GetVinProps(DbRESTFulRepository repository, dynamic vin)
        {
            //车型，车系，年款，版本，车架号，品牌，品牌代码，变速箱，车身颜色，发动机，发动机类型，排量，生产日期
            List<Get_Model_InfoResult._props> props = new List<Get_Model_InfoResult._props>();
            props.Add(new Get_Model_InfoResult._props { key = "车型", value = vin.name });
            props.Add(new Get_Model_InfoResult._props { key = "生产日期", value = vin.productionDate?.ToString() });
            props.Add(new Get_Model_InfoResult._props { key = "车身颜色", value = $"{vin.cColour} - {vin.cColourName}" });
            props.Add(new Get_Model_InfoResult._props { key = "内饰颜色", value = $"{vin.tColour} - {vin.tColourName}" });
            props.Add(new Get_Model_InfoResult._props { key = "Destination", value = vin.destinationCode });
            props.Add(new Get_Model_InfoResult._props { key = "MainOptionCode", value = vin.mainOptionCode });
            props.Add(new Get_Model_InfoResult._props { key = "BodyModel", value = vin.bodyModel });
            return props.Where(q => !string.IsNullOrEmpty(q.value)).ToList();
        }

        protected override List<Get_Model_InfoResult._features> GetVinFeatures(DbRESTFulRepository repository, dynamic vin)
        {
            List<Get_Model_InfoResult._features> features = new List<Get_Model_InfoResult._features>();
            if (!string.IsNullOrEmpty(vin.family1))
            {
                features.Add(new Get_Model_InfoResult._features { key = vin.family1, value = $"{vin.option1} - {vin.optionName1}" });
            }
            if (!string.IsNullOrEmpty(vin.family2))
            {
                features.Add(new Get_Model_InfoResult._features { key = vin.family2, value = $"{vin.option2} - {vin.optionName2}" });
            }
            if (!string.IsNullOrEmpty(vin.family3))
            {
                features.Add(new Get_Model_InfoResult._features { key = vin.family3, value = $"{vin.option3} - {vin.optionName3}" });
            }
            if (!string.IsNullOrEmpty(vin.family4))
            {
                features.Add(new Get_Model_InfoResult._features { key = vin.family4, value = $"{vin.option4} - {vin.optionName4}" });
            }
            if (!string.IsNullOrEmpty(vin.family5))
            {
                features.Add(new Get_Model_InfoResult._features { key = vin.family5, value = $"{vin.option5} - {vin.optionName5}" });
            }
            if (!string.IsNullOrEmpty(vin.family6))
            {
                features.Add(new Get_Model_InfoResult._features { key = vin.family6, value = $"{vin.option6} - {vin.optionName6}" });
            }
            if (!string.IsNullOrEmpty(vin.family7))
            {
                features.Add(new Get_Model_InfoResult._features { key = vin.family7, value = $"{vin.option7} - {vin.optionName7}" });
            }
            return features;
        }
    }
}
